package com.mingqijia.gassafety.authority.dal.helper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.command.FindDictionaryItemCommand;
import com.mingqijia.gassafety.authority.dal.handler.ConfigureTranslator;
import com.mingqijia.gassafety.authority.dal.provider.ConfigureProvider;
import com.mingqijia.gassafety.authority.dal.provider.DictionaryProvider;
import com.mingqijia.gassafety.db.entity.auth.DictionaryItemEntry;
import com.mingqijia.gassafety.db.entity.auth.ParamConfigEntry;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.enums.ParamType;
import com.mingqijia.gassafety.shared.enums.RunningState;
import com.mingqijia.gassafety.shared.enums.YesNoEnum;
import com.mingqijia.gassafety.shared.handler.GlobalAuthenticationException;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.Constants.*;

/**
 * 配置信息处理
 * @author Damon S.
 * @version v0.2
 * @date {YEAR}年{MONTH}月{DAY}日 {TIME}
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ConfigureHolder {

    private final ConfigureTranslator translator;
    private final ConfigureProvider provider1;
    private final DictionaryProvider provider2;

    public List<DictionaryItemRespDTO> getIndustryTypeZJ() {
        List<DictionaryItemRespDTO> industryType = this.getDictionaryByKey(INDUSTRY_TYPE_CODE);
//        DictionaryItemRespDTO residentDto = new DictionaryItemRespDTO();
//        residentDto.setName(ZJ_INDUSTRY_TYPE_STR);
//        residentDto.setValue(ZJ_INDUSTRY_TYPE);
//        industryType.add(residentDto);
        return industryType;
    }
    public List<DictionaryItemRespDTO> getIndustryTypeZJ(List<String> spIds){
        List<DictionaryItemRespDTO> industryType = this.getDictionaryByKeys( INDUSTRY_TYPE_CODE, spIds );
        DictionaryItemRespDTO residentDto = new DictionaryItemRespDTO();
        residentDto.setName(ZJ_INDUSTRY_TYPE_STR);
        residentDto.setValue(ZJ_INDUSTRY_TYPE);
        industryType.add(residentDto);
        Set<String> set = new HashSet<>();
        List<DictionaryItemRespDTO> respDTOS = new ArrayList<>();
        for (DictionaryItemRespDTO dto : industryType) {
            if (set.add(dto.getValue())){
                respDTOS.add(dto);
            }
        }
        return respDTOS;
    }


//    @Cacheable(value = Constants.CACHE_KEY_CONFIGURE, keyGenerator = "keyGenerator")
    public String getConfigByKey(String key) {
        return getConfigByKeyNoCache(key);
    }

    public String getConfigByKeyNoCache(String key) {
        // 获取当前企业下的配置
        ParamConfigEntry entry = provider1.getConfigByKey(
                key, ParamType.CONFIG, ApplicationUtils.getHeaderSpId());
        // 如果当前企业下没有此配置，则获取平台级的配置
        if (ObjectUtils.isEmpty(entry)) {
            entry = provider1.getConfigByKey(
                    key, ParamType.CONFIG, Constants.PLATFORM_SP);
            // 可继承的参数不再向集团获取
            if (!ObjectUtils.isEmpty(entry) && YesNoEnum.Y.getCode() == entry.getConfigurable()) {
                log.error("该企业指定参数不存在[code={}]", key);
                throw new GlobalAuthenticationException("错误：[该企业" + key + "]参数不存在");
            }
        }
        return ObjectUtils.isEmpty(entry) ? null : entry.getValue();
    }

//    @Cacheable(value = Constants.CACHE_KEY_DICTIONARY, keyGenerator = "keyGenerator")
    public List<DictionaryItemRespDTO> getDictionaryByKey(String dictCode) {
        return getDictionaryByKeyNoCache(dictCode,null);
    }

    public List<DictionaryItemRespDTO> getDictionaryByKeys(String dictCode,List<String> spIds) {
        List<DictionaryItemRespDTO> originalList = new ArrayList<>();
        List<DictionaryItemRespDTO> uniqueList = new ArrayList<>();
        for (String spId : spIds) {
            List<DictionaryItemRespDTO> dictionaryByKeyNoCache = getDictionaryByKeyNoCache(dictCode, spId);
            originalList.addAll(dictionaryByKeyNoCache);
        }
        Set<String> strings = new HashSet<>();
        for (DictionaryItemRespDTO dto : originalList) {
            //去重
            if (strings.add(dto.getValue())){
                uniqueList.add(dto);
            }
        }
        return uniqueList;
    }

    public List<DictionaryItemRespDTO> getDictionaryByKey(String dictCode,String spId) {
        return getDictionaryByKeyNoCache(dictCode,spId);
    }

    public List<DictionaryItemRespDTO> getDictionaryByKeyNoCache(String dictCode,String spId) {
        if (StringUtils.isEmpty(spId)) {
            spId = ApplicationUtils.getHeaderSpId();
        }
        List<DictionaryItemRespDTO> items = getDictionaryItemBySpId(
                dictCode, spId);
        if (CollectionUtils.isEmpty(items)) {
            ParamConfigEntry entry = provider1.getConfigByKey(
                    dictCode, ParamType.DICTIONARY, Constants.PLATFORM_SP);
            // 可继承的参数不再向集团获取
            if (!ObjectUtils.isEmpty(entry) && YesNoEnum.Y.getCode() == entry.getConfigurable()) {
                log.error("该企业指定参数不存在[code={}]", dictCode);
                throw new GlobalAuthenticationException("错误：[该企业" + dictCode + "]参数不存在");
            }
            items = getDictionaryItemBySpId(dictCode, Constants.PLATFORM_SP);
        }
        return items;
    }


    public List<DictionaryItemRespDTO> getDictionaryItemBySpId(String dictCode, String spId) {
        FindDictionaryItemCommand command = FindDictionaryItemCommand.builder()
                .dictCode(dictCode).dictState(RunningState.RUNNING).spId(spId)
                .page(Constants.LONG_ONE).pageSize(Constants.LONG_1_KILO).build();
        Page<DictionaryItemEntry> entries;
        try {
            entries = provider2.find(command);
        } catch (Exception e) {
            log.info("企业spId=【{}】下找不到此字典[dictCode={}]，从平台下获取", spId, dictCode);
            command = FindDictionaryItemCommand.builder().spId(Constants.PLATFORM_SP)
                    .page(Constants.LONG_ONE).pageSize(Constants.LONG_1_KILO)
                    .dictCode(dictCode).dictState(RunningState.RUNNING).build();
            entries = provider2.find(command);
        }
        return translator.toItemRespDTO(entries.getRecords());
    }


//    @Cacheable(value = Constants.CACHE_KEY_DICT_MAP, keyGenerator = "keyGenerator")
    public Map<String, DictionaryItemRespDTO> getDictionaryInMap(String dictCode) {
        List<DictionaryItemRespDTO> items = getDictionaryByKey(dictCode);
        if (CollectionUtils.isEmpty(items)) {
            return Collections.emptyMap();
        }
        Map<String, DictionaryItemRespDTO> map = new HashMap<>(items.size());
        for (DictionaryItemRespDTO item : items) {
            map.put(item.getValue(), item);
        }
        return map;
    }
}
